import React, { Component } from 'react';
// import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Form, Switch, Field, Balloon, Button, Select, Message } from '@teamix/ui';
import { Header, Content, ButtonIcon, Title } from '@alife/devops-ui';
import ListLoading from 'atComponents/ListLoading';
import track, { enterPage, Perf } from 'utils/track';
import * as actions from '../actions/index';
import BtnConfirm from './btnConfirm';
import docs from 'utils/docs';
import { ENUM } from 'utils/constants';
import { navigateOpen } from 'utils/router';
import isEqual from 'lodash.isequal';
import utils from 'utils';
import LogDialog from './logDialog';
import intl from '../../../../../../../../../locale';

const { regions } = ENUM;
const FormItem = Form.Item;
const formItemLayout = {
  labelCol: {
    fixedSpan: 6,
  },

  wrapperCol: {
    span: 14,
  },
};

const SUCCESS = 2;
const ALL_FAIL = 3;
const SOME_FAILE = 4;
const backupStatusMap = {
  [SUCCESS]: intl.get({ id: 'code-assets.backup.containers.root.Success', defaultMessage: '成功' }),
  [ALL_FAIL]: intl.get({ id: 'code-assets.backup.containers.root.Failed', defaultMessage: '失败' }),
  [SOME_FAILE]: intl.get({
    id: 'code-assets.backup.containers.root.PartiallyFailed',
    defaultMessage: '部分失败',
  }),
};

class Root extends Component {
  constructor(props) {
    super(props);
    this.field = new Field(this);
  }

  componentDidMount() {
    document.title = intl.get({
      id: 'code-assets.backup.containers.root.WarehouseBackupCloudEffectCodeup',
      defaultMessage: '仓库备份 · 云效 Codeup',
    });
    this.props.getBackupSpaceInfo();

    enterPage('Organization-Settings-Backup', {
      sendPerf: false,
    });
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    if (nextProps.formInitData && nextProps.formInitData !== this.props.formInitData) {
      this.field.setValues({
        name: nextProps.formInitData.name || '',
        location: nextProps.formInitData.location || '',
      });
    }
  }

  getIsFormNotChanged = () => {
    const { formInitData } = this.props;
    const formData = this.field.getValues();
    return isEqual(formData, formInitData);
  };

  componentWillUnmount() {
    this.props.clearTimer();
    this.props.resetData();
  }

  openOssAuthPage = () => {
    const { isAuthorizing } = this.props;
    if (isAuthorizing) {
      return;
    }
    track({
      action: 'authorized oss',
      page: 'Organization-Settings-backup',
      type: '',
      control: '',
    });

    const { space_authorization_link, space_authorization_role } = this.props.backupSpaceInfo || {};
    const openedWindow = navigateOpen(space_authorization_link);
    const windowChecker = setInterval(() => {
      if (openedWindow.location.pathname === '/oauth/aliyun/success') {
        window.clearInterval(windowChecker);
        this.props.backupAuthorize(space_authorization_role);
        if (!openedWindow.closed) {
          openedWindow.close();
        }
      }
    }, 500);
  };

  // 创建时调用create接口，修改时调用updateSetting接口
  saveSpace = () => {
    const { isCreatingSpace, backupSpaceInfo } = this.props;
    if (this.getIsFormNotChanged()) {
      return;
    }
    if (isCreatingSpace) {
      return;
    }
    this.field.validate((errors) => {
      if (!errors) {
        const formData = this.field.getValues();
        if (backupSpaceInfo.space_id) {
          this.props.updateBackupSpace({
            space_id: backupSpaceInfo.space_id,
            is_open_auto_back_up: backupSpaceInfo.is_open_auto_back_up,
            space_location: formData.location,
            space_name: formData.name,
          });
        } else {
          this.props.createBackupSpace({
            space_location: formData.location,
            space_name: formData.name,
            service_authorization_id: backupSpaceInfo && backupSpaceInfo.service_authorization_id,
          });
        }
      }
    });
  };

  toggleSwitch = (value) => {
    const { isToggleSetting, backupSpaceInfo } = this.props;
    if (isToggleSetting) {
      return;
    }
    if (value) {
      track({
        action: 'open timed backup',
        page: 'Organization-Settings-backup',
        type: '',
        control: '',
      });
    } else {
      track({
        action: 'close timed backup',
        page: 'Organization-Settings-backup',
        type: '',
        control: '',
      });
    }
    this.props.updateBackupSpace({
      space_id: backupSpaceInfo.space_id,
      is_open_auto_back_up: value,
      space_location: backupSpaceInfo.space_location,
      space_name: backupSpaceInfo.space_name,
    });
  };

  renderLog = (log) => {
    return (
      <div className="backup-item-time">
        <div>
          {intl.get({
            id: 'code-assets.backup.containers.root.LastExecutionTime',
            defaultMessage: '最近执行时间',
          })}
          {utils.getBeautyTime(log.gmt_modified)}
        </div>
        <div>
          {intl.get({
            id: 'code-assets.backup.containers.root.ExecutionResult',
            defaultMessage: '执行结果:',
          })}
          <span
            className={`backup-item-time-status ${log.status === SUCCESS ? 'success' : 'fail'}`}
          >
            {backupStatusMap[log.status]}
          </span>
        </div>
        {[ALL_FAIL, SOME_FAILE].includes(log.status) && (
          <div>
            <LogDialog
              record_no={log.record_no}
              trigger={
                <Button type="primary" text>
                  {intl.get({
                    id: 'code-assets.backup.containers.root.ViewLogs',
                    defaultMessage: '查看日志',
                  })}
                </Button>
              }
            />
          </div>
        )}
      </div>
    );
  };

  renderAuthBtn = (is_has_pending_back_up) => {
    return (
      <Button
        text
        type="normal"
        className={`relieve-btn ${is_has_pending_back_up ? 'pending' : ''}`}
        disabled={is_has_pending_back_up}
      >
        {intl.get({
          id: 'code-assets.backup.containers.root.RevokeAuthorization',
          defaultMessage: '解除授权',
        })}
      </Button>
    );
  };

  render() {
    const {
      isLoading,
      backupSpaceInfo,
      bucketNames,
      isLoadingBucketNames,
      isCreatingSpace,
      isManualPending,
    } = this.props;
    const { init } = this.field;

    const {
      service_authorization_id,
      is_open_auto_back_up,
      is_has_pending_back_up,
      space_add_link,
      space_opt_link,
      auto_back_up_logs = [],
      manual_back_up_logs = [],
      back_up_process,
      ownerName,
      owner,
      space_id,
      backup_repo_size,
    } = backupSpaceInfo;

    const isManualInProgress =
      is_has_pending_back_up && back_up_process && back_up_process.type === 'MANUAL';

    const showAddBucketBtn =
      !space_id || (window.FORCE.user && Number(window.FORCE.user.codeUserId) === owner);

    return (
      <>
        <Header
          title={intl.get({
            id: 'code-assets.backup.containers.root.VaultBackup',
            defaultMessage: '仓库备份',
          })}
          description={
            <div>
              {intl.get({
                id: 'code-assets.backup.containers.root.ProvidesEnterpriseLevelBackupCapabilities',
                defaultMessage:
                  '提供企业级备份能力，支持自动备份至指定存储空间（暂仅支持备份2G内的代码库）。',
              })}

              <a href={docs('backup')} target="_blank" className="backup-docs" rel="noreferrer">
                {intl.get({
                  id: 'code-assets.backup.containers.root.LearnMore',
                  defaultMessage: '了解更多',
                })}
              </a>
            </div>
          }
        />

        <Content>
          {isLoading ? (
            <ListLoading />
          ) : (
            <div className="backup-form">
              <div className="backup-item">
                <div className="backup-item-left">
                  <div className="backup-item-title">
                    {intl.get({
                      id: 'code-assets.backup.containers.root.BackupSpace',
                      defaultMessage: '备份空间',
                    })}

                    <Balloon
                      closable={false}
                      trigger={
                        <ButtonIcon
                          text
                          name="question-line"
                          style={{
                            marginLeft: 4,
                            display: 'inline-block',
                            position: 'relative',
                            top: '-1px',
                          }}
                        />
                      }
                      align="t"
                    >
                      {intl.get({
                        id: 'code-assets.backup.containers.root.OssChargesASmallAmount',
                        defaultMessage: '使用 OSS 服务会产生少量存储费用，详情参考',
                      })}

                      <a href={docs('oss')} target="_blank" rel="noreferrer">
                        {intl.get({
                          id: 'code-assets.backup.containers.root.OssBillingStandard',
                          defaultMessage: 'OSS计费标准',
                        })}
                      </a>
                    </Balloon>
                  </div>
                  {!service_authorization_id ? (
                    <React.Fragment>
                      <div className="backup-item-desc">
                        {intl.get({
                          id: 'code-assets.backup.containers.root.YouCanUseAlibabaCloud',
                          defaultMessage:
                            '支持使用阿里云对象存储服务（OSS）备份数据，请先绑定存储空间',
                        })}{' '}
                        <a className="no-href-with-click" onClick={this.openOssAuthPage}>
                          {intl.get({
                            id: 'code-assets.backup.containers.root.AuthorizeOss',
                            defaultMessage: '授权OSS服务',
                          })}
                        </a>
                      </div>
                      <div className="backup-message">
                        <Message type="notice">
                          <div className="message-content">
                            {intl.get({
                              id: 'code-assets.backup.containers.root.TheTotalNumberOfCode',
                              defaultMessage: '企业当前可备份代码库总量约',
                            })}
                            {backup_repo_size}
                            {intl.get({
                              id: 'code-assets.backup.containers.root.SupportsFullAndIncrementalBackup',
                              defaultMessage: '，支持全量+增量备份模式，详情参见',
                            })}
                            <a href={docs('backup-rules')} target="_blank" rel="noreferrer">
                              {intl.get({
                                id: 'code-assets.backup.containers.root.BackupRuleDescription',
                                defaultMessage: '备份规则说明',
                              })}
                            </a>
                          </div>
                        </Message>
                      </div>
                    </React.Fragment>
                  ) : (
                    <div className="backup-item-detail">
                      <div className="backup-item-detail-left">
                        <Form field={this.field} labelAlign="left" labelTextAlign="left">
                          {ownerName && (
                            <FormItem
                              {...formItemLayout}
                              label={intl.get({
                                id: 'code-assets.backup.containers.root.Authorizer',
                                defaultMessage: '授权人：',
                              })}
                            >
                              <div className="backup-item-detail-left-owner">
                                <Title align="t" trigger={<span>{ownerName}</span>}>
                                  {ownerName}
                                </Title>
                              </div>
                            </FormItem>
                          )}

                          <FormItem
                            {...formItemLayout}
                            label={intl.get({
                              id: 'code-assets.backup.containers.root.BucketRegion',
                              defaultMessage: 'Bucket 区域：',
                            })}
                          >
                            <Select
                              showSearch
                              {...init('location', {
                                initValue: '',
                                rules: [
                                  {
                                    required: true,
                                    message: intl.get({
                                      id: 'code-assets.backup.containers.root.ThisParameterIsRequired',
                                      defaultMessage: '该项为必填项',
                                    }),
                                  },
                                ],
                                props: {
                                  onChange: () => {
                                    this.field.setValue('name', '');
                                  },
                                },
                              })}
                              disabled={is_has_pending_back_up}
                              style={{ width: 200 }}
                            >
                              {regions.map((item) => {
                                return (
                                  <Select.Option value={item.value} key={item.value}>
                                    {item.label}
                                  </Select.Option>
                                );
                              })}
                            </Select>
                          </FormItem>

                          <FormItem
                            {...formItemLayout}
                            label={intl.get({
                              id: 'code-assets.backup.containers.root.BucketName',
                              defaultMessage: 'Bucket 名称：',
                            })}
                          >
                            <Select
                              showSearch
                              {...init('name', {
                                initValue: '',
                                rules: [
                                  {
                                    required: true,
                                    message: intl.get({
                                      id: 'code-assets.backup.containers.root.ThisParameterIsRequired',
                                      defaultMessage: '该项为必填项',
                                    }),
                                  },
                                ],
                              })}
                              disabled={is_has_pending_back_up}
                              onFocus={() => {
                                this.field.getValue('location') &&
                                  this.props.getBucketNames(this.field.getValue('location'));
                              }}
                              state={isLoadingBucketNames ? 'loading' : undefined}
                              style={{ width: 200 }}
                            >
                              {bucketNames.map((item) => {
                                const diabled = !item.supportStorageBucket;
                                return (
                                  <Select.Option
                                    value={item.spaceName}
                                    disabled={diabled}
                                    key={item.spaceName}
                                  >
                                    {diabled ? (
                                      <Balloon.Tooltip
                                        align="t"
                                        trigger={
                                          <div className="bucket-disabled-menu-item">
                                            {item.spaceName}
                                          </div>
                                        }
                                      >
                                        {intl.get({
                                          id: 'code-assets.backup.containers.root.CurrentlyArchiveBucketsAreNot',
                                          defaultMessage: '暂不支持归档存储类型Bucket',
                                        })}
                                      </Balloon.Tooltip>
                                    ) : (
                                      item.spaceName
                                    )}
                                  </Select.Option>
                                );
                              })}
                            </Select>
                            {showAddBucketBtn && (
                              <Balloon.Tooltip
                                align="t"
                                trigger={
                                  <ButtonIcon
                                    type="primary"
                                    name="add-fill"
                                    className="go-bucket-list"
                                    onClick={() => {
                                      navigateOpen(space_add_link);
                                    }}
                                  />
                                }
                              >
                                {intl.get({
                                  id: 'code-assets.backup.containers.root.NewBucketName',
                                  defaultMessage: '新建 Bucket 名称',
                                })}
                              </Balloon.Tooltip>
                            )}
                          </FormItem>
                          {is_has_pending_back_up ? (
                            <div className="save-btn">
                              <Balloon.Tooltip
                                align="t"
                                trigger={
                                  <Button type="primary" disabled>
                                    {intl.get({
                                      id: 'code-assets.backup.containers.root.Save',
                                      defaultMessage: '保存',
                                    })}
                                  </Button>
                                }
                              >
                                {intl.get({
                                  id: 'code-assets.backup.containers.root.TheBackupIsInProgress',
                                  defaultMessage: '存在执行中的备份',
                                })}
                              </Balloon.Tooltip>
                            </div>
                          ) : (
                            <Button
                              type="primary"
                              disabled={this.getIsFormNotChanged()}
                              loading={isCreatingSpace}
                              className="save-btn"
                              onClick={this.saveSpace}
                            >
                              {intl.get({
                                id: 'code-assets.backup.containers.root.Save',
                                defaultMessage: '保存',
                              })}
                            </Button>
                          )}
                        </Form>
                      </div>
                      <div className="backup-item-detail-right">
                        {space_opt_link && (
                          <Button
                            text
                            type="primary"
                            className="go-btn"
                            component="a"
                            href={space_opt_link}
                            target="_blank"
                          >
                            {intl.get({
                              id: 'code-assets.backup.containers.root.GoToTheBackupSpace',
                              defaultMessage: '前往备份空间',
                            })}
                          </Button>
                        )}

                        <BtnConfirm
                          trigger={
                            is_has_pending_back_up ? (
                              <Balloon.Tooltip
                                trigger={this.renderAuthBtn(is_has_pending_back_up)}
                                align="l"
                              >
                                {intl.get({
                                  id: 'code-assets.backup.containers.root.TheErrorMessageReturnedBecause',
                                  defaultMessage: '存在执行中的备份任务，暂不支持解除授权',
                                })}
                              </Balloon.Tooltip>
                            ) : (
                              this.renderAuthBtn(is_has_pending_back_up)
                            )
                          }
                          onClick={() => {
                            if (is_has_pending_back_up) {
                              return;
                            }
                            this.props.removeBackupAuth(service_authorization_id);
                          }}
                          needPopConfirm={!is_has_pending_back_up}
                        />
                      </div>
                    </div>
                  )}
                </div>
              </div>
              <div className="backup-item">
                <div className="backup-item-left">
                  <div className="backup-item-title">
                    {intl.get({
                      id: 'code-assets.backup.containers.root.ScheduledBackup',
                      defaultMessage: '定时备份',
                    })}
                  </div>
                  <div className="backup-item-desc">
                    {intl.get({
                      id: 'code-assets.backup.containers.root.AutomaticBackupOnTheSame',
                      defaultMessage: '开启当天及每间隔 7 天自动执行备份',
                    })}
                  </div>
                  {auto_back_up_logs &&
                    auto_back_up_logs.map((log) => {
                      return this.renderLog(log);
                    })}
                </div>
                {/* 未授权或者有备份中不可开启定时备份 */}
                <span className="backup-item-right">
                  {space_id && !is_has_pending_back_up ? (
                    <Switch
                      className="backup-item-switch"
                      name="ip_whitelist_enabled"
                      checked={is_open_auto_back_up}
                      onChange={this.toggleSwitch}
                    />
                  ) : (
                    <Balloon.Tooltip
                      align="tl"
                      trigger={
                        <Switch
                          className="backup-item-switch"
                          name="ip_whitelist_enabled"
                          checked={is_open_auto_back_up}
                          disabled
                        />
                      }
                      popupContainer={(trigger) => trigger.parentNode}
                    >
                      {is_has_pending_back_up
                        ? intl.get({
                            id: 'code-assets.backup.containers.root.TheBackupTaskIsIn',
                            defaultMessage: '存在执行中的备份任务，不支持重复触发',
                          })
                        : intl.get({
                            id: 'code-assets.backup.containers.root.TheErrorMessageReturnedBecause.1',
                            defaultMessage: '定时备份暂不可用，请先设置备份空间',
                          })}
                    </Balloon.Tooltip>
                  )}
                </span>
              </div>
              <div className="backup-item">
                <div className="backup-item-left">
                  <div className="backup-item-title">
                    {intl.get({
                      id: 'code-assets.backup.containers.root.ManualBackup',
                      defaultMessage: '手动备份',
                    })}
                  </div>
                  <div className="backup-item-desc">
                    {intl.get({
                      id: 'code-assets.backup.containers.root.ManuallyTriggerABackupImmediately',
                      defaultMessage: '手动立即触发一次备份',
                    })}
                  </div>
                  {manual_back_up_logs &&
                    manual_back_up_logs.map((log) => {
                      return this.renderLog(log);
                    })}
                </div>
                <span className="backup-item-right">
                  {/* 手动备份中： 执行中；自动备份中：不支持重复触发；默认： 立即备份 */}
                  {space_id && (!is_has_pending_back_up || isManualInProgress) ? (
                    <Button
                      type="primary"
                      className="backup-item-btn manual-btn"
                      onClick={() => {
                        if (isManualPending || isManualInProgress) {
                          return;
                        }
                        track({
                          action: 'set manual backup',
                          page: 'Organization-Settings-backup',
                          type: '',
                          control: '',
                        });

                        this.props.manualBackup();
                      }}
                      loading={isManualInProgress}
                    >
                      {isManualInProgress ? (
                        <span>
                          {intl.get({
                            id: 'code-assets.backup.containers.root.Executing',
                            defaultMessage: '执行中',
                          })}
                        </span>
                      ) : (
                        intl.get({
                          id: 'code-assets.backup.containers.root.BackUpNow',
                          defaultMessage: '立即备份',
                        })
                      )}
                    </Button>
                  ) : (
                    <Balloon.Tooltip
                      align="tl"
                      trigger={
                        <Button type="primary" className="backup-item-btn manual-btn" disabled>
                          {intl.get({
                            id: 'code-assets.backup.containers.root.BackUpNow',
                            defaultMessage: '立即备份',
                          })}
                        </Button>
                      }
                      popupContainer={(trigger) => trigger.parentNode}
                    >
                      {is_has_pending_back_up
                        ? intl.get({
                            id: 'code-assets.backup.containers.root.TheBackupTaskIsIn',
                            defaultMessage: '存在执行中的备份任务，不支持重复触发',
                          })
                        : intl.get({
                            id: 'code-assets.backup.containers.root.ManualBackupIsCurrentlyUnavailable',
                            defaultMessage: '手动备份暂不可用，请先设置备份空间',
                          })}
                    </Balloon.Tooltip>
                  )}
                </span>
              </div>
              <Perf page="Organization-Settings-Backup" />
            </div>
          )}
        </Content>
      </>
    );
  }
}

export default connect(
  (state) => state.organization.settings.backup,
  (dispatch) => bindActionCreators(actions, dispatch),
)(Root);
